package com.wwdx.service.impl;

import com.wwdx.BaseCommons;
import com.wwdx.model.*;
import com.wwdx.model.dto.BasePayDTO;
import com.wwdx.service.PayServiceI;
import com.wwdx.utils.ConstantHolder;
import org.joda.time.Days;
import org.joda.time.LocalDate;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.Date;

/**
 * 支付（回调）业务处理
 * @author liguoliang
 * @date 2017-12-29
 */
@Service
public class PayServiceImpl extends BaseCommons implements PayServiceI {

    /**
     * 生成订单信息
     */
    @Override
    public BasePayDTO.PayModel save(MerchantOrderModel model) {
        BasePayDTO.PayModel payModel = new BasePayDTO.PayModel();
        if (model == null) {
            payModel.setError("参数错误");
            return payModel;
        }
        String openId = model.getOpenId(),productName,productDetail;
        Integer type = model.getType();
        Long productId = model.getProductId();
        //查询非会员产品是否购买
        if (type != ConstantHolder.Constant.VIPTYPE){
            Integer isorder = userService.isorder(productId, openId,model.getMerchantId());
            if (isorder == 1){
                payModel.setError("已经购买此产品");
                return payModel;
            }
        }
        //产品价格
        BigDecimal price;
        switch (type){
                //主题
            case ConstantHolder.Constant.THEMETYPE:
                WwdxThemeModel wwdxThemeModel = wwdxThemeService.getByThemeId(productId);
                productName = wwdxThemeModel.getTitle();
                productDetail = wwdxThemeModel.getContentabstract();
                price = wwdxThemeModel.getPrice();
                break;
                //书籍
            case ConstantHolder.Constant.BOOKTYPE:
                //小课
            case ConstantHolder.Constant.SMALLBOOKTYPE:
                WwdxBookModel wwdxBookModel = wwdxBookService.getByBookId(productId);
                productName = wwdxBookModel.getBookname();
                productDetail = wwdxBookModel.getContentsummary();
                price = wwdxBookModel.getBookprice();
                break;
                //会员
            case ConstantHolder.Constant.VIPTYPE:
                WwdxVipProductModel wwdxVipProductModel = wwdxVipProductService.getByProductId(productId);
                productName = "会员充值";
                productDetail = "会员充值";
                price = wwdxVipProductModel.getPrice();
                break;
            default:
                payModel.setError("没有查到此商品");
                return payModel;
        }
        payModel.setProductPrice(price);
        payModel.setProductName(productName);
        payModel.setProductdetails(productDetail);
        payModel.setOrderno(model.getOrderNo());

        model.setPrice(price);
        model.setGmtCreated(new Date());
        model.setStatus(0);
        merchantOrderService.save(model);
        return payModel;
    }

    /**
     * 更新订单信息
     */
    @Override
    public void payBackHandler(BasePayDTO.PayCallBackDTO dto){
        MerchantOrderModel wwdxOrderModel = merchantOrderService.getByOrderNo(dto.getTradeNo());
        if (wwdxOrderModel == null){
            return;
        }
        Integer status = wwdxOrderModel.getStatus();
        if (status == null || status == 0){
            wwdxOrderModel.setStatus(1);
            wwdxOrderModel.setPayTime(new Date());
            merchantOrderService.update(wwdxOrderModel);
            Integer type = wwdxOrderModel.getType();
            Long productId = wwdxOrderModel.getProductId();
            String openId = wwdxOrderModel.getOpenId();
            //会员充值
            if (type == ConstantHolder.Constant.VIPTYPE){
                this.vipRecharge(openId,productId);
            }else {
                //主题、书籍、小课购买
                taskExecutor.execute(()-> userService.purchase(openId,productId,type));
            }
        }
    }

    /**
     * 会员充值
     * @param openId 用户业务ID
     * @param productId 产品ID
     */
    @Override
    public void vipRecharge(String openId, Long productId){
        WwdxVipProductModel wwdxVipProductModel = wwdxVipProductService.getByProductId(productId);
        Integer type = wwdxVipProductModel.getType();
        WwdxVipUserModel wwdxVipUserModel = wwdxVipUserService.getByOpenId(openId);
        if (wwdxVipUserModel == null){
            this.saveVip(type,openId);
        }else {
            this.updateVip(type,wwdxVipUserModel);
        }
    }

    /**
     * 续费充值
     * @param type VIP类型 {@link PayServiceImpl#plusDays(int, Object)}
     * @param model 会员信息
     */
    private void updateVip(Integer type,WwdxVipUserModel model){
        LocalDate localDate = new LocalDate();
        String expireTime = model.getExpireTime();
        int days = Days.daysBetween(new LocalDate(expireTime),localDate).getDays();
        //过期操作
        if (days > 0){
            model.setEffectTime(localDate.toString());
            localDate = this.plusDays(type, localDate);
        }else {
            localDate = this.plusDays(type, expireTime);
        }
        model.setExpireTime(localDate.toString());
        if (type == 1){
            model.setType(1);
        }
        model.setSubscribe(1);
        wwdxVipUserService.update(model);
    }

    /**
     * 首次充值
     * @param type VIP类型 {@link PayServiceImpl#plusDays(int, Object)}
     * @param openId 用户业务ID
     */
    private void saveVip(Integer type,String openId){
        LocalDate localDate = new LocalDate();
        LocalDate date = this.plusDays(type, localDate);
        WwdxVipUserModel wwdxVipUserModel = WwdxVipUserModel.builder()
                .effectTime(localDate.toString()).expireTime(date.toString())
                .unionid(openId).subscribe(1).type(type == 1 ? 1 : 0).build();
        wwdxVipUserService.save(wwdxVipUserModel);
    }

    /**
     * 会员新增天数
     * @param type 会员类型
     * @param date 生效时间 类型为: {@link java.util.Date} or {@link java.lang.String}
     *
     * @return 过期时间
     */
    private LocalDate plusDays(int type,Object date){
        LocalDate localDate = new LocalDate(date);
        switch (type){
            //加一周
            case 1:
                localDate = localDate.plusWeeks(1);
                break;
            //加一月
            case 2:
                localDate = localDate.plusMonths(1);
                break;
            //加一年
            case 10:
                localDate = localDate.plusYears(1);
                break;
            //加半月
            case 4:
                localDate = localDate.plusDays(15);
                break;
            //加3天
            case 5:
                localDate = localDate.plusDays(3);
                break;
            //加5天
            case 6:
                localDate = localDate.plusDays(5);
                break;
            //加三个月
            case 8:
                localDate = localDate.plusMonths(3);
                break;
            //加半年
            case 9:
                localDate = localDate.plusMonths(6);
                break;
            //加100天
            case 11:
                localDate = localDate.plusDays(100);
                break;
            default:
                break;
        }
        return localDate;
    }
}